import Watcher from "../watcher.js";
import Vue from "../index.js";

/**
 * 根据处理好的render进行编译
 */
export default function mountComponent(vm) {
  /**
   * updateComponent更新组件的的函数
   * 当data修改时候调用vm._update函数实行页面响应时
   */
  const updateComponent = () => {
    /**
     * vm._render() 返回的是处理过的ast对象
     */
    vm._update(vm._render());
  };
  // 实例化一个渲染 Watcher，当响应式数据更新时，这个更新函数会被执行
  new Watcher(updateComponent);
}

/**
 * 负责执行 vm.$options.render 函数
 */
Vue.prototype._render = function () {
  /**
   * 给 render 函数绑定 this 上下文为 Vue 实例
   * this.$options.render 返回的是一个渲染函数 用来虚拟dom节点
   */
  return this.$options.render.apply(this);
};

/*
 * 负责对比节点完成更新
 */
Vue.prototype._update = function (vnode) {
  // 老的 VNode
  const prevVNode = this._vnode;
  // 新的 VNode
  this._vnode = vnode;
  // debugger;
  if (!prevVNode) {
    // 老的 VNode 不存在，则说明时首次渲染根组件
    // this.$el 老节点
    // vnode 新节点
    this.$el = this.__patch__(this.$el, vnode);
  } else {
    // 后续更新组件或者首次渲染子组件，都会走这里
    this.$el = this.__patch__(prevVNode, vnode);
  }
};
